package com.tiancheng.trade.payment.util.helper;

import com.tiancheng.trade.payment.enums.OperationTypeEnum;
import com.tiancheng.trade.commom.core.enums.PaymentChannelEnum;
import org.apache.commons.lang3.StringUtils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;

/**
 * 支付、退款编号生成
 *
 * @author supeicheng
 * @date 2024/3/12
 */
public class PaymentIdHelper {
    /**
     * 银联渠道订单前缀
     */
    /*private static final String umsMerOrderIdPre = ServiceLocator.getBean(UmsAllConfigs.class).getMerOrderIdPre();
    private static final String umsQrMerOrderIdPre = ServiceLocator.getBean(UmsAllConfigs.class).getQrcProperties().getMerOrderIdPre();*/

    /**
     * 获取支付流水号
     *
     * @param uid
     * @param paymentChannel 渠道
     * @param RuleParam      额外的规则参数
     * @return
     */
    public static String getPay(String uid, String paymentChannel, Object RuleParam, String umsMerOrderIdPre) {
//        long id = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() << 12) | Math.abs(uid.hashCode()) | CommonUtil.getRandom(10, 10000000);
        StringBuilder paymentId = new StringBuilder();
        // 银联商务流水号处理，需要加固定前缀
        if (PaymentChannelEnum.UMS.getCode().equals(paymentChannel) || PaymentChannelEnum.UMS_DHJT.getCode().equals(paymentChannel)
                || PaymentChannelEnum.UMS_MOP.getCode().equals(paymentChannel)) {
            if (null != RuleParam && "notPay".equalsIgnoreCase(RuleParam.toString())) {
                // not pay的支付单号单独标识一下吧
                return ("10NP" + paymentId.append(OperationTypeEnum.pay.getCode()).append(getGeneralId(uid)).toString());
            }
            return (umsMerOrderIdPre + paymentId.append(OperationTypeEnum.pay.getCode()).append(getGeneralId(uid)).toString());
        } else if ("ums_qrc".equals(paymentChannel)) {
            return (umsMerOrderIdPre + paymentId.append(OperationTypeEnum.pay.getCode()).append(getGeneralId(uid)).toString());
        } else {
            if (StringUtils.isNotEmpty(umsMerOrderIdPre)) {
                return umsMerOrderIdPre + paymentId.append(OperationTypeEnum.pay.getCode()).append(getGeneralId(uid)).toString();
            }
        }
        return paymentId.append(OperationTypeEnum.pay.getCode()).append(getGeneralId(uid)).toString();
    }

    /**
     * 获取二维码支付流水号
     *
     * @param uid
     * @return
     */
    public static String getQrPay(String uid, String umsQrMerOrderIdPre) {
//        long id = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() << 12) | Math.abs(uid.hashCode()) | CommonUtil.getRandom(10, 10000000);
        StringBuilder paymentId = new StringBuilder();
        // 银联商务流水号处理，需要加固定前缀
        final StringBuilder generalId = getGeneralId(uid);
        return umsQrMerOrderIdPre + paymentId.append(OperationTypeEnum.pay.getCode()).append(generalId.substring(4, generalId.length())).toString();
    }

    /**
     * 获取退款流水号
     *
     * @param uid
     * @param paymentChannel 渠道
     * @param RuleParam      额外的规则参数
     * @return
     */
    public static String getRefund(String uid, String paymentChannel, Object RuleParam, String umsMerOrderIdPre) {
//        long id = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() << 12) | Math.abs(uid.hashCode()) | CommonUtil.getRandom(10, 10000000);
        StringBuilder paymentId = new StringBuilder();

        // 银联商务流水号处理，需要加固定前缀
        if (PaymentChannelEnum.UMS.getCode().equals(paymentChannel) || PaymentChannelEnum.UMS_DHJT.getCode().equals(paymentChannel)
                || PaymentChannelEnum.UMS_MOP.getCode().equals(paymentChannel)) {
            if (null != RuleParam && "notPay".equalsIgnoreCase(RuleParam.toString())) {
                // not pay的支付单号单独标识一下吧
                return ("10NP" + paymentId.append(OperationTypeEnum.refund.getCode()).append(getGeneralId(uid)).toString());
            }
            return (umsMerOrderIdPre + paymentId.append(OperationTypeEnum.refund.getCode()).append(getGeneralId(uid)));
        } else {
            if (StringUtils.isNotEmpty(umsMerOrderIdPre)) {
                return umsMerOrderIdPre + paymentId.append(OperationTypeEnum.refund.getCode()).append(getGeneralId(uid)).toString();
            }
        }
        return paymentId.append(OperationTypeEnum.refund.getCode()).append(getGeneralId(uid)).toString();
    }

    /**
     * 获取结算批次号
     *
     * @return
     */
    public static String getSettleBatchNo(Long orgPaymentChannelId) {
//        long id = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() << 12) | Math.abs(uid.hashCode()) | CommonUtil.getRandom(10, 10000000);
        StringBuilder paymentId = new StringBuilder();
        // 银联商务流水号处理，需要加固定前缀
        final StringBuilder generalId = getGeneralId(String.valueOf(orgPaymentChannelId));
        return "SP" + paymentId.append(OperationTypeEnum.settle.getCode()).append(generalId.substring(4, generalId.length())).toString();
    }

    /**
     * 获取结算流水号
     *
     * @param flowId
     * @return
     */
    public static String getWithdrawalFlowId(String flowId) {
        StringBuilder paymentId = new StringBuilder();
        // 银联商务流水号处理，需要加固定前缀
        final StringBuilder generalId = getGeneralId(flowId);
        return paymentId.append(OperationTypeEnum.settle.getCode()).append(generalId) +"S";
    }


    /**
     * 获取结算流水号
     *
     * @param flowId
     * @return
     */
    public static String getSettleFlowId(String flowId, String orderIdPre) {
        if (StringUtils.isEmpty(orderIdPre)) {
            orderIdPre = "";
        }
//        long id = (LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli() << 12) | Math.abs(uid.hashCode()) | CommonUtil.getRandom(10, 10000000);
        StringBuilder paymentId = new StringBuilder();
        // 银联商务流水号处理，需要加固定前缀
        final StringBuilder generalId = getGeneralId(flowId);
        return orderIdPre  + paymentId.append(OperationTypeEnum.settle.getCode()).append(generalId) +"S";
    }



    /**
     * 获取通用规则id
     *
     * @param uid
     * @return
     */
    private static StringBuilder getGeneralId(String uid) {
        StringBuilder id = new StringBuilder();

        int random = (int) ((Math.random() * 9 + 1) * 1000);
        String uidHashCode = String.valueOf(Math.abs(uid.hashCode() + random));
        uidHashCode = uidHashCode.substring(uidHashCode.length() >= 6 ? uidHashCode.length() - 6 : 0);

        id.append(LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli()).append(uidHashCode);
        return id;
    }

    /**
     * 子流水号生成规则
     *
     * @param flowId 主订单流水
     * @param suffix 后缀序列
     * @return
     */
    public static String getSubOrderFlowId(String flowId, int suffix) {
        return (flowId + String.format("%02d", suffix));
    }
}
